Visualization with R - packages, colors and transparencies
#### packages
library("igraph")
Attaching package: ‘igraph’
The following objects are masked from ‘package:stats’:
decompose, spectrum
The following object is masked from ‘package:base’:
union
library("network")
network: Classes for Relational Data
Version 1.13.0 created on 2015-08-31.
copyright (c) 2005, Carter T. Butts, University of California-Irvine
Mark S. Handcock, University of California -- Los Angeles
David R. Hunter, Penn State University
Martina Morris, University of Washington
Skye Bender-deMoll, University of Washington
For citation information, type citation("network").
Type help("network-package") to get started.
Attaching package: ‘network’
The following objects are masked from ‘package:igraph’:
%c%, %s%, add.edges, add.vertices, delete.edges,
delete.vertices, get.edge.attribute, get.edges,
get.vertex.attribute, is.bipartite, is.directed,
list.edge.attributes, list.vertex.attributes,
set.edge.attribute, set.vertex.attribute
library("sna")
package ‘sna’ was built under R version 3.2.5Loading required package: statnet.common
sna: Tools for Social Network Analysis
Version 2.4 created on 2016-07-23.
copyright (c) 2005, Carter T. Butts, University of California-Irvine
For citation information, type citation("sna").
Type help(package="sna") to get started.
Attaching package: ‘sna’
The following objects are masked from ‘package:igraph’:
betweenness, bonpow, closeness, components, degree,
dyad.census, evcent, hierarchy, is.connected,
neighborhood, triad.census
library("visNetwork")
package ‘visNetwork’ was built under R version 3.2.5
Attaching package: ‘visNetwork’
The following object is masked from ‘package:igraph’:
%>%
library("threejs")
package ‘threejs’ was built under R version 3.2.4
library("networkD3")
package ‘networkD3’ was built under R version 3.2.5
library("ndtv")
package ‘ndtv’ was built under R version 3.2.5Loading required package: networkDynamic
networkDynamic: version 0.9.0, created on 2016-01-12
Copyright (c) 2016, Carter T. Butts, University of California -- Irvine
Ayn Leslie-Cook, University of Washington
Pavel N. Krivitsky, University of Wollongong
Skye Bender-deMoll, University of Washington
with contributions from
Zack Almquist, University of California -- Irvine
David R. Hunter, Penn State University
Li Wang
Kirk Li, University of Washington
Steven M. Goodreau, University of Washington
Jeffrey Horner
Martina Morris, University of Washington
Based on "statnet" project software (statnet.org).
For license and citation information see statnet.org/attribution
or type citation("networkDynamic").
Loading required package: animation
package ‘animation’ was built under R version 3.2.5
ndtv: version 0.10.0, created on 2016-5-6
Copyright (c) 2016, Skye Bender-deMoll, University of Washington
with contributions from
Martina Morris, University of Washington
Based on "statnet" project software (statnet.org).
For license and citation information see statnet.org/attribution
or type citation("ndtv").
library('RColorBrewer')
#### colors
plot(x=1:10, y=rep(5,10), pch=19, cex=3, col="dark red")
points(x=1:10, y=rep(6, 10), pch=19, cex=3, col="557799")
points(x=1:10, y=rep(4, 10), pch=19, cex=3, col=rgb(.25, .5, .3))

## listing colors
colors() # List all named colors
[1] "white" "aliceblue"
[3] "antiquewhite" "antiquewhite1"
[5] "antiquewhite2" "antiquewhite3"
[7] "antiquewhite4" "aquamarine"
[9] "aquamarine1" "aquamarine2"
[11] "aquamarine3" "aquamarine4"
[13] "azure" "azure1"
[15] "azure2" "azure3"
[17] "azure4" "beige"
[19] "bisque" "bisque1"
[21] "bisque2" "bisque3"
[23] "bisque4" "black"
[25] "blanchedalmond" "blue"
[27] "blue1" "blue2"
[29] "blue3" "blue4"
[31] "blueviolet" "brown"
[33] "brown1" "brown2"
[35] "brown3" "brown4"
[37] "burlywood" "burlywood1"
[39] "burlywood2" "burlywood3"
[41] "burlywood4" "cadetblue"
[43] "cadetblue1" "cadetblue2"
[45] "cadetblue3" "cadetblue4"
[47] "chartreuse" "chartreuse1"
[49] "chartreuse2" "chartreuse3"
[51] "chartreuse4" "chocolate"
[53] "chocolate1" "chocolate2"
[55] "chocolate3" "chocolate4"
[57] "coral" "coral1"
[59] "coral2" "coral3"
[61] "coral4" "cornflowerblue"
[63] "cornsilk" "cornsilk1"
[65] "cornsilk2" "cornsilk3"
[67] "cornsilk4" "cyan"
[69] "cyan1" "cyan2"
[71] "cyan3" "cyan4"
[73] "darkblue" "darkcyan"
[75] "darkgoldenrod" "darkgoldenrod1"
[77] "darkgoldenrod2" "darkgoldenrod3"
[79] "darkgoldenrod4" "darkgray"
[81] "darkgreen" "darkgrey"
[83] "darkkhaki" "darkmagenta"
[85] "darkolivegreen" "darkolivegreen1"
[87] "darkolivegreen2" "darkolivegreen3"
[89] "darkolivegreen4" "darkorange"
[91] "darkorange1" "darkorange2"
[93] "darkorange3" "darkorange4"
[95] "darkorchid" "darkorchid1"
[97] "darkorchid2" "darkorchid3"
[99] "darkorchid4" "darkred"
[101] "darksalmon" "darkseagreen"
[103] "darkseagreen1" "darkseagreen2"
[105] "darkseagreen3" "darkseagreen4"
[107] "darkslateblue" "darkslategray"
[109] "darkslategray1" "darkslategray2"
[111] "darkslategray3" "darkslategray4"
[113] "darkslategrey" "darkturquoise"
[115] "darkviolet" "deeppink"
[117] "deeppink1" "deeppink2"
[119] "deeppink3" "deeppink4"
[121] "deepskyblue" "deepskyblue1"
[123] "deepskyblue2" "deepskyblue3"
[125] "deepskyblue4" "dimgray"
[127] "dimgrey" "dodgerblue"
[129] "dodgerblue1" "dodgerblue2"
[131] "dodgerblue3" "dodgerblue4"
[133] "firebrick" "firebrick1"
[135] "firebrick2" "firebrick3"
[137] "firebrick4" "floralwhite"
[139] "forestgreen" "gainsboro"
[141] "ghostwhite" "gold"
[143] "gold1" "gold2"
[145] "gold3" "gold4"
[147] "goldenrod" "goldenrod1"
[149] "goldenrod2" "goldenrod3"
[151] "goldenrod4" "gray"
[153] "gray0" "gray1"
[155] "gray2" "gray3"
[157] "gray4" "gray5"
[159] "gray6" "gray7"
[161] "gray8" "gray9"
[163] "gray10" "gray11"
[165] "gray12" "gray13"
[167] "gray14" "gray15"
[169] "gray16" "gray17"
[171] "gray18" "gray19"
[173] "gray20" "gray21"
[175] "gray22" "gray23"
[177] "gray24" "gray25"
[179] "gray26" "gray27"
[181] "gray28" "gray29"
[183] "gray30" "gray31"
[185] "gray32" "gray33"
[187] "gray34" "gray35"
[189] "gray36" "gray37"
[191] "gray38" "gray39"
[193] "gray40" "gray41"
[195] "gray42" "gray43"
[197] "gray44" "gray45"
[199] "gray46" "gray47"
[201] "gray48" "gray49"
[203] "gray50" "gray51"
[205] "gray52" "gray53"
[207] "gray54" "gray55"
[209] "gray56" "gray57"
[211] "gray58" "gray59"
[213] "gray60" "gray61"
[215] "gray62" "gray63"
[217] "gray64" "gray65"
[219] "gray66" "gray67"
[221] "gray68" "gray69"
[223] "gray70" "gray71"
[225] "gray72" "gray73"
[227] "gray74" "gray75"
[229] "gray76" "gray77"
[231] "gray78" "gray79"
[233] "gray80" "gray81"
[235] "gray82" "gray83"
[237] "gray84" "gray85"
[239] "gray86" "gray87"
[241] "gray88" "gray89"
[243] "gray90" "gray91"
[245] "gray92" "gray93"
[247] "gray94" "gray95"
[249] "gray96" "gray97"
[251] "gray98" "gray99"
[253] "gray100" "green"
[255] "green1" "green2"
[257] "green3" "green4"
[259] "greenyellow" "grey"
[261] "grey0" "grey1"
[263] "grey2" "grey3"
[265] "grey4" "grey5"
[267] "grey6" "grey7"
[269] "grey8" "grey9"
[271] "grey10" "grey11"
[273] "grey12" "grey13"
[275] "grey14" "grey15"
[277] "grey16" "grey17"
[279] "grey18" "grey19"
[281] "grey20" "grey21"
[283] "grey22" "grey23"
[285] "grey24" "grey25"
[287] "grey26" "grey27"
[289] "grey28" "grey29"
[291] "grey30" "grey31"
[293] "grey32" "grey33"
[295] "grey34" "grey35"
[297] "grey36" "grey37"
[299] "grey38" "grey39"
[301] "grey40" "grey41"
[303] "grey42" "grey43"
[305] "grey44" "grey45"
[307] "grey46" "grey47"
[309] "grey48" "grey49"
[311] "grey50" "grey51"
[313] "grey52" "grey53"
[315] "grey54" "grey55"
[317] "grey56" "grey57"
[319] "grey58" "grey59"
[321] "grey60" "grey61"
[323] "grey62" "grey63"
[325] "grey64" "grey65"
[327] "grey66" "grey67"
[329] "grey68" "grey69"
[331] "grey70" "grey71"
[333] "grey72" "grey73"
[335] "grey74" "grey75"
[337] "grey76" "grey77"
[339] "grey78" "grey79"
[341] "grey80" "grey81"
[343] "grey82" "grey83"
[345] "grey84" "grey85"
[347] "grey86" "grey87"
[349] "grey88" "grey89"
[351] "grey90" "grey91"
[353] "grey92" "grey93"
[355] "grey94" "grey95"
[357] "grey96" "grey97"
[359] "grey98" "grey99"
[361] "grey100" "honeydew"
[363] "honeydew1" "honeydew2"
[365] "honeydew3" "honeydew4"
[367] "hotpink" "hotpink1"
[369] "hotpink2" "hotpink3"
[371] "hotpink4" "indianred"
[373] "indianred1" "indianred2"
[375] "indianred3" "indianred4"
[377] "ivory" "ivory1"
[379] "ivory2" "ivory3"
[381] "ivory4" "khaki"
[383] "khaki1" "khaki2"
[385] "khaki3" "khaki4"
[387] "lavender" "lavenderblush"
[389] "lavenderblush1" "lavenderblush2"
[391] "lavenderblush3" "lavenderblush4"
[393] "lawngreen" "lemonchiffon"
[395] "lemonchiffon1" "lemonchiffon2"
[397] "lemonchiffon3" "lemonchiffon4"
[399] "lightblue" "lightblue1"
[401] "lightblue2" "lightblue3"
[403] "lightblue4" "lightcoral"
[405] "lightcyan" "lightcyan1"
[407] "lightcyan2" "lightcyan3"
[409] "lightcyan4" "lightgoldenrod"
[411] "lightgoldenrod1" "lightgoldenrod2"
[413] "lightgoldenrod3" "lightgoldenrod4"
[415] "lightgoldenrodyellow" "lightgray"
[417] "lightgreen" "lightgrey"
[419] "lightpink" "lightpink1"
[421] "lightpink2" "lightpink3"
[423] "lightpink4" "lightsalmon"
[425] "lightsalmon1" "lightsalmon2"
[427] "lightsalmon3" "lightsalmon4"
[429] "lightseagreen" "lightskyblue"
[431] "lightskyblue1" "lightskyblue2"
[433] "lightskyblue3" "lightskyblue4"
[435] "lightslateblue" "lightslategray"
[437] "lightslategrey" "lightsteelblue"
[439] "lightsteelblue1" "lightsteelblue2"
[441] "lightsteelblue3" "lightsteelblue4"
[443] "lightyellow" "lightyellow1"
[445] "lightyellow2" "lightyellow3"
[447] "lightyellow4" "limegreen"
[449] "linen" "magenta"
[451] "magenta1" "magenta2"
[453] "magenta3" "magenta4"
[455] "maroon" "maroon1"
[457] "maroon2" "maroon3"
[459] "maroon4" "mediumaquamarine"
[461] "mediumblue" "mediumorchid"
[463] "mediumorchid1" "mediumorchid2"
[465] "mediumorchid3" "mediumorchid4"
[467] "mediumpurple" "mediumpurple1"
[469] "mediumpurple2" "mediumpurple3"
[471] "mediumpurple4" "mediumseagreen"
[473] "mediumslateblue" "mediumspringgreen"
[475] "mediumturquoise" "mediumvioletred"
[477] "midnightblue" "mintcream"
[479] "mistyrose" "mistyrose1"
[481] "mistyrose2" "mistyrose3"
[483] "mistyrose4" "moccasin"
[485] "navajowhite" "navajowhite1"
[487] "navajowhite2" "navajowhite3"
[489] "navajowhite4" "navy"
[491] "navyblue" "oldlace"
[493] "olivedrab" "olivedrab1"
[495] "olivedrab2" "olivedrab3"
[497] "olivedrab4" "orange"
[499] "orange1" "orange2"
[501] "orange3" "orange4"
[503] "orangered" "orangered1"
[505] "orangered2" "orangered3"
[507] "orangered4" "orchid"
[509] "orchid1" "orchid2"
[511] "orchid3" "orchid4"
[513] "palegoldenrod" "palegreen"
[515] "palegreen1" "palegreen2"
[517] "palegreen3" "palegreen4"
[519] "paleturquoise" "paleturquoise1"
[521] "paleturquoise2" "paleturquoise3"
[523] "paleturquoise4" "palevioletred"
[525] "palevioletred1" "palevioletred2"
[527] "palevioletred3" "palevioletred4"
[529] "papayawhip" "peachpuff"
[531] "peachpuff1" "peachpuff2"
[533] "peachpuff3" "peachpuff4"
[535] "peru" "pink"
[537] "pink1" "pink2"
[539] "pink3" "pink4"
[541] "plum" "plum1"
[543] "plum2" "plum3"
[545] "plum4" "powderblue"
[547] "purple" "purple1"
[549] "purple2" "purple3"
[551] "purple4" "red"
[553] "red1" "red2"
[555] "red3" "red4"
[557] "rosybrown" "rosybrown1"
[559] "rosybrown2" "rosybrown3"
[561] "rosybrown4" "royalblue"
[563] "royalblue1" "royalblue2"
[565] "royalblue3" "royalblue4"
[567] "saddlebrown" "salmon"
[569] "salmon1" "salmon2"
[571] "salmon3" "salmon4"
[573] "sandybrown" "seagreen"
[575] "seagreen1" "seagreen2"
[577] "seagreen3" "seagreen4"
[579] "seashell" "seashell1"
[581] "seashell2" "seashell3"
[583] "seashell4" "sienna"
[585] "sienna1" "sienna2"
[587] "sienna3" "sienna4"
[589] "skyblue" "skyblue1"
[591] "skyblue2" "skyblue3"
[593] "skyblue4" "slateblue"
[595] "slateblue1" "slateblue2"
[597] "slateblue3" "slateblue4"
[599] "slategray" "slategray1"
[601] "slategray2" "slategray3"
[603] "slategray4" "slategrey"
[605] "snow" "snow1"
[607] "snow2" "snow3"
[609] "snow4" "springgreen"
[611] "springgreen1" "springgreen2"
[613] "springgreen3" "springgreen4"
[615] "steelblue" "steelblue1"
[617] "steelblue2" "steelblue3"
[619] "steelblue4" "tan"
[621] "tan1" "tan2"
[623] "tan3" "tan4"
[625] "thistle" "thistle1"
[627] "thistle2" "thistle3"
[629] "thistle4" "tomato"
[631] "tomato1" "tomato2"
[633] "tomato3" "tomato4"
[635] "turquoise" "turquoise1"
[637] "turquoise2" "turquoise3"
[639] "turquoise4" "violet"
[641] "violetred" "violetred1"
[643] "violetred2" "violetred3"
[645] "violetred4" "wheat"
[647] "wheat1" "wheat2"
[649] "wheat3" "wheat4"
[651] "whitesmoke" "yellow"
[653] "yellow1" "yellow2"
[655] "yellow3" "yellow4"
[657] "yellowgreen"
grep("blue", colors(), value=T) # Colors that have "blue" in the name
[1] "aliceblue" "blue" "blue1"
[4] "blue2" "blue3" "blue4"
[7] "blueviolet" "cadetblue" "cadetblue1"
[10] "cadetblue2" "cadetblue3" "cadetblue4"
[13] "cornflowerblue" "darkblue" "darkslateblue"
[16] "deepskyblue" "deepskyblue1" "deepskyblue2"
[19] "deepskyblue3" "deepskyblue4" "dodgerblue"
[22] "dodgerblue1" "dodgerblue2" "dodgerblue3"
[25] "dodgerblue4" "lightblue" "lightblue1"
[28] "lightblue2" "lightblue3" "lightblue4"
[31] "lightskyblue" "lightskyblue1" "lightskyblue2"
[34] "lightskyblue3" "lightskyblue4" "lightslateblue"
[37] "lightsteelblue" "lightsteelblue1" "lightsteelblue2"
[40] "lightsteelblue3" "lightsteelblue4" "mediumblue"
[43] "mediumslateblue" "midnightblue" "navyblue"
[46] "powderblue" "royalblue" "royalblue1"
[49] "royalblue2" "royalblue3" "royalblue4"
[52] "skyblue" "skyblue1" "skyblue2"
[55] "skyblue3" "skyblue4" "slateblue"
[58] "slateblue1" "slateblue2" "slateblue3"
[61] "slateblue4" "steelblue" "steelblue1"
[64] "steelblue2" "steelblue3" "steelblue4"
pal1 <- heat.colors(5, alpha=1) # 5 colors from the heat palette, opaque
pal2 <- rainbow(5, alpha=.5) # 5 colors from the heat palette, transparent
plot(x=1:10, y=1:10, pch=19, cex=5, col=pal1)

plot(x=1:10, y=1:10, pch=19, cex=5, col=pal2)

## generate our own colors : colorRampPalette
palf <- colorRampPalette(c("gray80", "dark red"))
plot(x=10:1, y=1:10, pch=19, cex=5, col=palf(10))

palf <- colorRampPalette(c(rgb(1,1,1, .2),rgb(.8,0,0, .7)), alpha=TRUE)
plot(x=10:1, y=1:10, pch=19, cex=5, col=palf(10))

## built-in colors : RColorBrewer
display.brewer.all()

display.brewer.pal(8, "Set3")

display.brewer.pal(8, "Spectral")

display.brewer.pal(8, "Blues")

pal3 <- brewer.pal(10, "Set3")
plot(x=10:1, y=10:1, pch=19, cex=6, col=pal3)

plot(x=10:1, y=10:1, pch=19, cex=6, col=rev(pal3)) # backwards

####################################
#### opacity : alpha
plot(x=1:5, y=rep(5,5), pch=19, cex=12, col=rgb(.25, .5, .3, alpha=.5), xlim=c(0,6))
## If we have a hex color representation, we can set the transparency alpha using adjustcolor from package grDevices
par(bg="gray40")

col.tr <- grDevices::adjustcolor("557799", alpha=0.7)
plot(x=1:5, y=rep(5,5), pch=19, cex=12, col=col.tr, xlim=c(0,6))

fonts
plot(x=10:1, y=10:1, pch=19, cex=3,
main="This is a plot", col="orange",
family="Arial Black" )

# First you may have to let R know where to find ghostscript on your machine:
#Sys.setenv(R_GSCMD = "C:/Program Files/gs/gs9.21/bin/gswin64c.exe")
# pdf() will send all the plots we output before dev.off() to a pdf file:
#pdf(file="ArialBlack.pdf")
plot(x=10:1, y=10:1, pch=19, cex=6,
main="This is a plot", col="orange",
family="Arial Black" )

#dev.off()
#embed_fonts("ArialBlack.pdf", outfile="ArialBlack_embed.pdf")
Dataset 1: input = edgelist
#### dataset 1
nodes <- read.csv("/Users/jiemingchen/R_codes/polnet2017_networks_tutorial/Data files/Dataset1-Media-Example-NODES.csv", header=T, as.is=T)
links <- read.csv("/Users/jiemingchen/R_codes/polnet2017_networks_tutorial/Data files/Dataset1-Media-Example-EDGES.csv", header=T, as.is=T)
## we have cases in the data where there are multiple links between the same two nodes.
## so collapse/aggregate all links of the same type between the same two nodes by summing their weights
links <- aggregate(links[,3], links[,-3], sum)
links <- links[order(links$from, links$to),]
colnames(links)[4] <- "weight"
rownames(links) <- NULL
## turning networks into igraph objects
## D or U, for a directed or undirected graph
## N for a named graph (where nodes have a name attribute)
## W for a weighted graph (where edges have a weight attribute)
## B for a bipartite (two-mode) graph (where nodes have a type attribute)
## The two numbers that follow (17 49) refer to the number of nodes and edges in the graph. The description also lists node & edge attributes, for example:
## (g/c) - graph-level character attribute
## (v/c) - vertex-level character attribute
## (e/n) - edge-level numeric attribute
net <- graph_from_data_frame(d=links, vertices=nodes, directed=T)
net
IGRAPH DNW- 17 49 --
+ attr: name (v/c), media (v/c), media.type (v/n), type.label
| (v/c), audience.size (v/n), type (e/c), weight (e/n)
+ edges (vertex names):
[1] s01->s02 s01->s03 s01->s04 s01->s15 s02->s01 s02->s03 s02->s09
[8] s02->s10 s03->s01 s03->s04 s03->s05 s03->s08 s03->s10 s03->s11
[15] s03->s12 s04->s03 s04->s06 s04->s11 s04->s12 s04->s17 s05->s01
[22] s05->s02 s05->s09 s05->s15 s06->s06 s06->s16 s06->s17 s07->s03
[29] s07->s08 s07->s10 s07->s14 s08->s03 s08->s07 s08->s09 s09->s10
[36] s10->s03 s12->s06 s12->s13 s12->s14 s13->s12 s13->s17 s14->s11
[43] s14->s13 s15->s01 s15->s04 s15->s06 s16->s06 s16->s17 s17->s04
## to look at the network
E(net) # The edges of the "net" object
+ 49/49 edges (vertex names):
[1] s01->s02 s01->s03 s01->s04 s01->s15 s02->s01 s02->s03 s02->s09
[8] s02->s10 s03->s01 s03->s04 s03->s05 s03->s08 s03->s10 s03->s11
[15] s03->s12 s04->s03 s04->s06 s04->s11 s04->s12 s04->s17 s05->s01
[22] s05->s02 s05->s09 s05->s15 s06->s06 s06->s16 s06->s17 s07->s03
[29] s07->s08 s07->s10 s07->s14 s08->s03 s08->s07 s08->s09 s09->s10
[36] s10->s03 s12->s06 s12->s13 s12->s14 s13->s12 s13->s17 s14->s11
[43] s14->s13 s15->s01 s15->s04 s15->s06 s16->s06 s16->s17 s17->s04
V(net) # The vertices of the "net" object
+ 17/17 vertices, named:
[1] s01 s02 s03 s04 s05 s06 s07 s08 s09 s10 s11 s12 s13 s14 s15 s16
[17] s17
E(net)$type # Edge attribute "type"
[1] "hyperlink" "hyperlink" "hyperlink" "mention" "hyperlink"
[6] "hyperlink" "hyperlink" "hyperlink" "hyperlink" "hyperlink"
[11] "hyperlink" "hyperlink" "mention" "hyperlink" "hyperlink"
[16] "hyperlink" "mention" "mention" "hyperlink" "mention"
[21] "mention" "hyperlink" "hyperlink" "mention" "hyperlink"
[26] "hyperlink" "mention" "mention" "mention" "hyperlink"
[31] "mention" "hyperlink" "mention" "mention" "mention"
[36] "hyperlink" "mention" "hyperlink" "mention" "hyperlink"
[41] "mention" "mention" "mention" "hyperlink" "hyperlink"
[46] "hyperlink" "hyperlink" "mention" "hyperlink"
V(net)$media # Vertex attribute "media"
[1] "NY Times" "Washington Post" "Wall Street Journal"
[4] "USA Today" "LA Times" "New York Post"
[7] "CNN" "MSNBC" "FOX News"
[10] "ABC" "BBC" "Yahoo News"
[13] "Google News" "Reuters.com" "NYTimes.com"
[16] "WashingtonPost.com" "AOL.com"
# Find nodes and edges by attribute:
# (that returns oblects of type vertex sequence/edge sequence)
V(net)[media=="BBC"]
+ 1/17 vertex, named:
[1] s11
E(net)[type=="mention"]
+ 20/49 edges (vertex names):
[1] s01->s15 s03->s10 s04->s06 s04->s11 s04->s17 s05->s01 s05->s15
[8] s06->s17 s07->s03 s07->s08 s07->s14 s08->s07 s08->s09 s09->s10
[15] s12->s06 s12->s14 s13->s17 s14->s11 s14->s13 s16->s17
# You can also examine the network matrix directly:
net[1,]
s01 s02 s03 s04 s05 s06 s07 s08 s09 s10 s11 s12 s13 s14 s15 s16 s17
0 22 22 21 0 0 0 0 0 0 0 0 0 0 20 0 0
net[5,7]
[1] 0
# Get an edge list or a matrix:
as_edgelist(net, names=T)
[,1] [,2]
[1,] "s01" "s02"
[2,] "s01" "s03"
[3,] "s01" "s04"
[4,] "s01" "s15"
[5,] "s02" "s01"
[6,] "s02" "s03"
[7,] "s02" "s09"
[8,] "s02" "s10"
[9,] "s03" "s01"
[10,] "s03" "s04"
[11,] "s03" "s05"
[12,] "s03" "s08"
[13,] "s03" "s10"
[14,] "s03" "s11"
[15,] "s03" "s12"
[16,] "s04" "s03"
[17,] "s04" "s06"
[18,] "s04" "s11"
[19,] "s04" "s12"
[20,] "s04" "s17"
[21,] "s05" "s01"
[22,] "s05" "s02"
[23,] "s05" "s09"
[24,] "s05" "s15"
[25,] "s06" "s06"
[26,] "s06" "s16"
[27,] "s06" "s17"
[28,] "s07" "s03"
[29,] "s07" "s08"
[30,] "s07" "s10"
[31,] "s07" "s14"
[32,] "s08" "s03"
[33,] "s08" "s07"
[34,] "s08" "s09"
[35,] "s09" "s10"
[36,] "s10" "s03"
[37,] "s12" "s06"
[38,] "s12" "s13"
[39,] "s12" "s14"
[40,] "s13" "s12"
[41,] "s13" "s17"
[42,] "s14" "s11"
[43,] "s14" "s13"
[44,] "s15" "s01"
[45,] "s15" "s04"
[46,] "s15" "s06"
[47,] "s16" "s06"
[48,] "s16" "s17"
[49,] "s17" "s04"
as_adjacency_matrix(net, attr="weight")
17 x 17 sparse Matrix of class "dgCMatrix"
[[ suppressing 17 column names ‘s01’, ‘s02’, ‘s03’ ... ]]
s01 . 22 22 21 . . . . . . . . . . 20 . .
s02 23 . 21 . . . . . 1 5 . . . . . . .
s03 21 . . 22 1 . . 4 . 2 1 1 . . . . .
s04 . . 23 . . 1 . . . . 22 3 . . . . 2
s05 1 21 . . . . . . 2 . . . . . 21 . .
s06 . . . . . 1 . . . . . . . . . 21 21
s07 . . 1 . . . . 22 . 21 . . . 4 . . .
s08 . . 2 . . . 21 . 23 . . . . . . . .
s09 . . . . . . . . . 21 . . . . . . .
s10 . . 2 . . . . . . . . . . . . . .
s11 . . . . . . . . . . . . . . . . .
s12 . . . . . 2 . . . . . . 22 22 . . .
s13 . . . . . . . . . . . 21 . . . . 1
s14 . . . . . . . . . . 1 . 21 . . . .
s15 22 . . 1 . 4 . . . . . . . . . . .
s16 . . . . . 23 . . . . . . . . . . 21
s17 . . . 4 . . . . . . . . . . . . .
# Or data frames describing nodes and edges:
as_data_frame(net, what="edges")
as_data_frame(net, what="vertices")
plot(net) # not a pretty picture!

Dataset 1: (cont’d) making more pretty pics
## remove loops in figure above
net <- simplify(net, remove.multiple = F, remove.loops = T)
## reduce arrow size and remove labels (set them to NA)
plot(net, edge.arrow.size=.4,vertex.label=NA)

# Plot with curved edges (edge.curved=.1) and reduce arrow size:
# Note that using curved edges will allow you to see multiple links
# between two nodes (e.g. links going in either direction, or multiplex links)
plot(net, edge.arrow.size=.4, edge.curved=.1)

# Set edge color to light gray, the node & border color to orange
# Replace the vertex label with the node names stored in "media"
plot(net, edge.arrow.size=.2, edge.color="orange",
vertex.color="orange", vertex.frame.color="#ffffff",
vertex.label=V(net)$media, vertex.label.color="black")

#### color our network nodes based on type of media
#### size them based on degree centrality (more links -> larger node)
#### change the width of the edges based on their weight
# Generate colors based on media type:
colrs <- c("gray50", "tomato", "gold")
V(net)$color <- colrs[V(net)$media.type]
# Compute node degrees (#links) and use that to set node size:
# note add igraph:: because there are 2 versions of degree
deg <- igraph::degree(net, mode="all")
V(net)$size <- deg*3
# We could also use the audience size value:
V(net)$size <- V(net)$audience.size*0.6
# The labels are currently node IDs.
# Setting them to NA will render no labels:
V(net)$label <- NA
# Set edge width based on weight:
E(net)$width <- E(net)$weight/6
# change arrow size and edge color:
E(net)$arrow.size <- .2
E(net)$edge.color <- "gray80"
E(net)$width <- 1+E(net)$weight/12
plot(net)

# this overrides the above in edge.color and vertex.color
# attributes, see plotting parameters below
plot(net, edge.color="orange", vertex.color="gray50")

# add legend
plot(net)
legend(x=-1.5, y=-1.1, c("Newspaper","Television", "Online News"), pch=21,
col="#777777", pt.bg=colrs, pt.cex=2, cex=.8, bty="n", ncol=1)

## different style with only labels for nodes
plot(net, vertex.shape="none", vertex.label=V(net)$media,
vertex.label.font=2, vertex.label.color="gray40",
vertex.label.cex=.7, edge.color="gray85")

## color the edges of the graph based on their source node color.
## get the starting node for each edge with the ends() igraph function: It returns the start and end vertex for edges listed in the es parameter. The names parameter control whether the function returns edge names or IDs.
edge.start <- ends(net, es=E(net), names=F)[,1]
edge.col <- V(net)$color[edge.start]
plot(net, edge.color=edge.col, edge.curved=.1)

network layouts
## all available layouts
layouts <- grep("^layout_", ls("package:igraph"), value=TRUE)[-1]
# Remove layouts that do not apply to our graph.
layouts <- layouts[!grepl("bipartite|merge|norm|sugiyama|tree", layouts)]
par(mfrow=c(3,3), mar=c(1,1,1,1))
for (layout in layouts) {
print(layout)
l <- do.call(layout, list(net))
plot(net, edge.arrow.mode=0, layout=l, main=layout) }
[1] "layout_as_star"
[1] "layout_components"
[1] "layout_in_circle"
[1] "layout_nicely"
[1] "layout_on_grid"
[1] "layout_on_sphere"
[1] "layout_randomly"
[1] "layout_with_dh"
[1] "layout_with_drl"
[1] "layout_with_fr"

[1] "layout_with_gem"
[1] "layout_with_graphopt"
[1] "layout_with_kk"
[1] "layout_with_lgl"
[1] "layout_with_mds"

some layout examples
### Barabasi-Albert model with sample_pa(n), n = #nodes
net.bg <- sample_pa(80)
V(net.bg)$size <- 8
V(net.bg)$frame.color <- "white"
V(net.bg)$color <- "orange"
V(net.bg)$label <- ""
E(net.bg)$arrow.mode <- 0
plot(net.bg)

### random layout
plot(net.bg, layout=layout_randomly)

# or
l <- layout_randomly(net.bg)
plot(net.bg, layout=l)

### circular layout
l <- layout_in_circle(net.bg)
plot(net.bg, layout=l)

### layout with fixed coordinates
l <- cbind(1:vcount(net.bg), c(1, vcount(net.bg):2))
plot(net.bg, layout=l)

### 3D sphere layout
l <- layout_on_sphere(net.bg)
plot(net.bg, layout=l)

Force-directed layouts
### Fruchterman-Reingold is one of the most used force-directed layout algorithms out there.
### Force-directed layouts try to get a nice-looking graph where edges are similar in length and cross each other as little as possible
### They simulate the graph as a physical system. Nodes are electrically charged particles that repulse each other when they get too close. The edges act as springs that attract connected nodes closer together. As a result, nodes are evenly distributed through the chart area, and the layout is intuitive in that nodes which share more connections are closer to each other. The disadvantage of these algorithms is that they are rather slow and therefore less often used in graphs larger than ~1000 vertices. You can set the “weight” parameter which increases the attraction forces among nodes connected by heavier edges.
### You will notice that this layout is not deterministic - different runs will result in slightly different configurations
l <- layout_with_fr(net.bg)
plot(net.bg, layout=l)
## You will notice that this layout is not deterministic - different runs will result in slightly different configurations.
par(mfrow=c(2,2), mar=c(0,0,0,0)) # plot four figures - 2 rows, 2 columns

plot(net.bg, layout=layout_with_fr)
plot(net.bg, layout=layout_with_fr)
plot(net.bg, layout=l)
plot(net.bg, layout=l)

dev.off()
null device
1
### Kamada Kawai force directed
### Like Fruchterman Reingold, it attempts to minimize the energy in a spring system.
l <- layout_with_kk(net.bg)
plot(net.bg, layout=l)

### The LGL algorithm is meant for large, connected graphs.
### Here you can also specify a root: a node that will be placed in the middle of the layout.
plot(net.bg, layout=layout_with_lgl)

MDS (multidimensional scaling) algorithm
## tries to place nodes based on some measure of similarity or distance between them. More similar nodes are plotted closer to each other. By default, the measure used is based on the shortest paths between nodes in the network. We can change that by using our own distance matrix (however defined) with the parameter dist. MDS layouts are nice because positions and distances have a clear interpretation. The problem with them is visual clarity: nodes often overlap, or are placed on top of each other.
plot(net.bg, layout=layout_with_mds)

plotting parameters
## ?igraph.plotting for more information.
## NODES
# vertex.color Node color
# vertex.frame.color Node border color
# vertex.shape One of “none”, “circle”, “square”, “csquare”, “rectangle”
# “crectangle”, “vrectangle”, “pie”, “raster”, or “sphere”
# vertex.size Size of the node (default is 15)
# vertex.size2 The second size of the node (e.g. for a rectangle)
# vertex.label Character vector used to label the nodes
# vertex.label.family Font family of the label (e.g.“Times”, “Helvetica”)
# vertex.label.font Font: 1 plain, 2 bold, 3, italic, 4 bold italic, 5 symbol
# vertex.label.cex Font size (multiplication factor, device-dependent)
# vertex.label.dist Distance between the label and the vertex
# vertex.label.degree The position of the label in relation to the vertex, where
# 0 is right, “pi” is left, “pi/2” is below, and “-pi/2” is above
# EDGES
# edge.color Edge color
# edge.width Edge width, defaults to 1
# edge.arrow.size Arrow size, defaults to 1
# edge.arrow.width Arrow width, defaults to 1
# edge.lty Line type, could be 0 or “blank”, 1 or “solid”, 2 or “dashed”,
# 3 or “dotted”, 4 or “dotdash”, 5 or “longdash”, 6 or “twodash”
# edge.label Character vector used to label edges
# edge.label.family Font family of the label (e.g.“Times”, “Helvetica”)
# edge.label.font Font: 1 plain, 2 bold, 3, italic, 4 bold italic, 5 symbol
# edge.label.cex Font size for edge labels
# edge.curved Edge curvature, range 0-1 (FALSE sets it to 0, TRUE to 0.5)
# arrow.mode Vector specifying whether edges should have arrows,
# possible values: 0 no arrow, 1 back, 2 forward, 3 both
# OTHER
# margin Empty space margins around the plot, vector with length 4
# frame if TRUE, the plot will be framed
# main If set, adds a title to the plot
# sub If set, adds a subtitle to the plot
# asp Numeric, the aspect ratio of a plot (y/x).
# palette A color palette to use for vertex color
# rescale Whether to rescale coordinates to [-1,1]. Default is TRUE.
LS0tCnRpdGxlOiAiUiBOb3RlYm9vayIKb3V0cHV0OiBodG1sX25vdGVib29rCi0tLQoKIyBWaXN1YWxpemF0aW9uIHdpdGggUiAtIHBhY2thZ2VzLCBjb2xvcnMgYW5kIHRyYW5zcGFyZW5jaWVzCmBgYHtyfQojIyMjIHBhY2thZ2VzCmxpYnJhcnkoImlncmFwaCIpIApsaWJyYXJ5KCJuZXR3b3JrIikgCmxpYnJhcnkoInNuYSIpCmxpYnJhcnkoInZpc05ldHdvcmsiKQpsaWJyYXJ5KCJ0aHJlZWpzIikKbGlicmFyeSgibmV0d29ya0QzIikKbGlicmFyeSgibmR0diIpCmxpYnJhcnkoJ1JDb2xvckJyZXdlcicpCgojIyMjIGNvbG9ycwpwbG90KHg9MToxMCwgeT1yZXAoNSwxMCksIHBjaD0xOSwgY2V4PTMsIGNvbD0iZGFyayByZWQiKQpwb2ludHMoeD0xOjEwLCB5PXJlcCg2LCAxMCksIHBjaD0xOSwgY2V4PTMsIGNvbD0iNTU3Nzk5IikKcG9pbnRzKHg9MToxMCwgeT1yZXAoNCwgMTApLCBwY2g9MTksIGNleD0zLCBjb2w9cmdiKC4yNSwgLjUsIC4zKSkKCiMjIGxpc3RpbmcgY29sb3JzCmNvbG9ycygpICAgICAgICAgICAgICAgICAgICAgICAgICAjIExpc3QgYWxsIG5hbWVkIGNvbG9ycwpncmVwKCJibHVlIiwgY29sb3JzKCksIHZhbHVlPVQpICAgIyBDb2xvcnMgdGhhdCBoYXZlICJibHVlIiBpbiB0aGUgbmFtZQpwYWwxIDwtIGhlYXQuY29sb3JzKDUsIGFscGhhPTEpICAgIyAgNSBjb2xvcnMgZnJvbSB0aGUgaGVhdCBwYWxldHRlLCBvcGFxdWUKcGFsMiA8LSByYWluYm93KDUsIGFscGhhPS41KSAgICAgICMgIDUgY29sb3JzIGZyb20gdGhlIGhlYXQgcGFsZXR0ZSwgdHJhbnNwYXJlbnQKcGxvdCh4PTE6MTAsIHk9MToxMCwgcGNoPTE5LCBjZXg9NSwgY29sPXBhbDEpCnBsb3QoeD0xOjEwLCB5PTE6MTAsIHBjaD0xOSwgY2V4PTUsIGNvbD1wYWwyKQoKIyMgZ2VuZXJhdGUgb3VyIG93biBjb2xvcnMgOiBjb2xvclJhbXBQYWxldHRlCnBhbGYgPC0gY29sb3JSYW1wUGFsZXR0ZShjKCJncmF5ODAiLCAiZGFyayByZWQiKSkgCnBsb3QoeD0xMDoxLCB5PTE6MTAsIHBjaD0xOSwgY2V4PTUsIGNvbD1wYWxmKDEwKSkgCnBhbGYgPC0gY29sb3JSYW1wUGFsZXR0ZShjKHJnYigxLDEsMSwgLjIpLHJnYiguOCwwLDAsIC43KSksIGFscGhhPVRSVUUpCnBsb3QoeD0xMDoxLCB5PTE6MTAsIHBjaD0xOSwgY2V4PTUsIGNvbD1wYWxmKDEwKSkgCgojIyBidWlsdC1pbiBjb2xvcnMgOiBSQ29sb3JCcmV3ZXIKZGlzcGxheS5icmV3ZXIuYWxsKCkKZGlzcGxheS5icmV3ZXIucGFsKDgsICJTZXQzIikKZGlzcGxheS5icmV3ZXIucGFsKDgsICJTcGVjdHJhbCIpCmRpc3BsYXkuYnJld2VyLnBhbCg4LCAiQmx1ZXMiKQoKcGFsMyA8LSBicmV3ZXIucGFsKDEwLCAiU2V0MyIpCnBsb3QoeD0xMDoxLCB5PTEwOjEsIHBjaD0xOSwgY2V4PTYsIGNvbD1wYWwzKQpwbG90KHg9MTA6MSwgeT0xMDoxLCBwY2g9MTksIGNleD02LCBjb2w9cmV2KHBhbDMpKSAjIGJhY2t3YXJkcwoKCiMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIwojIyMjIG9wYWNpdHkgOiBhbHBoYQpwbG90KHg9MTo1LCB5PXJlcCg1LDUpLCBwY2g9MTksIGNleD0xMiwgY29sPXJnYiguMjUsIC41LCAuMywgYWxwaGE9LjUpLCB4bGltPWMoMCw2KSkKCiMjIElmIHdlIGhhdmUgYSBoZXggY29sb3IgcmVwcmVzZW50YXRpb24sIHdlIGNhbiBzZXQgdGhlIHRyYW5zcGFyZW5jeSBhbHBoYSB1c2luZyBhZGp1c3Rjb2xvciBmcm9tIHBhY2thZ2UgZ3JEZXZpY2VzCnBhcihiZz0iZ3JheTQwIikKY29sLnRyIDwtIGdyRGV2aWNlczo6YWRqdXN0Y29sb3IoIjU1Nzc5OSIsIGFscGhhPTAuNykKcGxvdCh4PTE6NSwgeT1yZXAoNSw1KSwgcGNoPTE5LCBjZXg9MTIsIGNvbD1jb2wudHIsIHhsaW09YygwLDYpKQpgYGAKCiMgZm9udHMKYGBge3J9CnBsb3QoeD0xMDoxLCB5PTEwOjEsIHBjaD0xOSwgY2V4PTMsIAogICAgIG1haW49IlRoaXMgaXMgYSBwbG90IiwgY29sPSJvcmFuZ2UiLCAKICAgICBmYW1pbHk9IkFyaWFsIEJsYWNrIiApCgojIEZpcnN0IHlvdSBtYXkgaGF2ZSB0byBsZXQgUiBrbm93IHdoZXJlIHRvIGZpbmQgZ2hvc3RzY3JpcHQgb24geW91ciBtYWNoaW5lOgojU3lzLnNldGVudihSX0dTQ01EID0gIkM6L1Byb2dyYW0gRmlsZXMvZ3MvZ3M5LjIxL2Jpbi9nc3dpbjY0Yy5leGUiKQoKIyBwZGYoKSB3aWxsIHNlbmQgYWxsIHRoZSBwbG90cyB3ZSBvdXRwdXQgYmVmb3JlIGRldi5vZmYoKSB0byBhIHBkZiBmaWxlOiAKI3BkZihmaWxlPSJBcmlhbEJsYWNrLnBkZiIpCnBsb3QoeD0xMDoxLCB5PTEwOjEsIHBjaD0xOSwgY2V4PTYsIAogICAgIG1haW49IlRoaXMgaXMgYSBwbG90IiwgY29sPSJvcmFuZ2UiLCAKICAgICBmYW1pbHk9IkFyaWFsIEJsYWNrIiApCiNkZXYub2ZmKCkKCiNlbWJlZF9mb250cygiQXJpYWxCbGFjay5wZGYiLCBvdXRmaWxlPSJBcmlhbEJsYWNrX2VtYmVkLnBkZiIpCmBgYAojIERhdGFzZXQgMTogaW5wdXQgPSBlZGdlbGlzdApgYGB7cn0KIyMjIyBkYXRhc2V0IDEgCm5vZGVzIDwtIHJlYWQuY3N2KCIvVXNlcnMvamllbWluZ2NoZW4vUl9jb2Rlcy9wb2xuZXQyMDE3X25ldHdvcmtzX3R1dG9yaWFsL0RhdGEgZmlsZXMvRGF0YXNldDEtTWVkaWEtRXhhbXBsZS1OT0RFUy5jc3YiLCBoZWFkZXI9VCwgYXMuaXM9VCkKbGlua3MgPC0gcmVhZC5jc3YoIi9Vc2Vycy9qaWVtaW5nY2hlbi9SX2NvZGVzL3BvbG5ldDIwMTdfbmV0d29ya3NfdHV0b3JpYWwvRGF0YSBmaWxlcy9EYXRhc2V0MS1NZWRpYS1FeGFtcGxlLUVER0VTLmNzdiIsIGhlYWRlcj1ULCBhcy5pcz1UKQoKIyMgd2UgaGF2ZSBjYXNlcyBpbiB0aGUgZGF0YSB3aGVyZSB0aGVyZSBhcmUgbXVsdGlwbGUgbGlua3MgYmV0d2VlbiB0aGUgc2FtZSB0d28gbm9kZXMuIAojIyBzbyBjb2xsYXBzZS9hZ2dyZWdhdGUgYWxsIGxpbmtzIG9mIHRoZSBzYW1lIHR5cGUgYmV0d2VlbiB0aGUgc2FtZSB0d28gbm9kZXMgYnkgc3VtbWluZyB0aGVpciB3ZWlnaHRzCmxpbmtzIDwtIGFnZ3JlZ2F0ZShsaW5rc1ssM10sIGxpbmtzWywtM10sIHN1bSkKbGlua3MgPC0gbGlua3Nbb3JkZXIobGlua3MkZnJvbSwgbGlua3MkdG8pLF0KY29sbmFtZXMobGlua3MpWzRdIDwtICJ3ZWlnaHQiCnJvd25hbWVzKGxpbmtzKSA8LSBOVUxMCgojIyB0dXJuaW5nIG5ldHdvcmtzIGludG8gaWdyYXBoIG9iamVjdHMKIyMgRCBvciBVLCBmb3IgYSBkaXJlY3RlZCBvciB1bmRpcmVjdGVkIGdyYXBoCiMjIE4gZm9yIGEgbmFtZWQgZ3JhcGggKHdoZXJlIG5vZGVzIGhhdmUgYSBuYW1lIGF0dHJpYnV0ZSkKIyMgVyBmb3IgYSB3ZWlnaHRlZCBncmFwaCAod2hlcmUgZWRnZXMgaGF2ZSBhIHdlaWdodCBhdHRyaWJ1dGUpCiMjIEIgZm9yIGEgYmlwYXJ0aXRlICh0d28tbW9kZSkgZ3JhcGggKHdoZXJlIG5vZGVzIGhhdmUgYSB0eXBlIGF0dHJpYnV0ZSkKIyMgVGhlIHR3byBudW1iZXJzIHRoYXQgZm9sbG93ICgxNyA0OSkgcmVmZXIgdG8gdGhlIG51bWJlciBvZiBub2RlcyBhbmQgZWRnZXMgaW4gdGhlIGdyYXBoLiBUaGUgZGVzY3JpcHRpb24gYWxzbyBsaXN0cyBub2RlICYgZWRnZSBhdHRyaWJ1dGVzLCBmb3IgZXhhbXBsZToKIyMgKGcvYykgLSBncmFwaC1sZXZlbCBjaGFyYWN0ZXIgYXR0cmlidXRlCiMjICh2L2MpIC0gdmVydGV4LWxldmVsIGNoYXJhY3RlciBhdHRyaWJ1dGUKIyMgKGUvbikgLSBlZGdlLWxldmVsIG51bWVyaWMgYXR0cmlidXRlCm5ldCA8LSBncmFwaF9mcm9tX2RhdGFfZnJhbWUoZD1saW5rcywgdmVydGljZXM9bm9kZXMsIGRpcmVjdGVkPVQpIApuZXQKCiMjIHRvIGxvb2sgYXQgdGhlIG5ldHdvcmsKRShuZXQpICAgICAgICMgVGhlIGVkZ2VzIG9mIHRoZSAibmV0IiBvYmplY3QKVihuZXQpICAgICAgICMgVGhlIHZlcnRpY2VzIG9mIHRoZSAibmV0IiBvYmplY3QKRShuZXQpJHR5cGUgICMgRWRnZSBhdHRyaWJ1dGUgInR5cGUiClYobmV0KSRtZWRpYSAjIFZlcnRleCBhdHRyaWJ1dGUgIm1lZGlhIgoKIyBGaW5kIG5vZGVzIGFuZCBlZGdlcyBieSBhdHRyaWJ1dGU6CiMgKHRoYXQgcmV0dXJucyBvYmxlY3RzIG9mIHR5cGUgdmVydGV4IHNlcXVlbmNlL2VkZ2Ugc2VxdWVuY2UpClYobmV0KVttZWRpYT09IkJCQyJdCkUobmV0KVt0eXBlPT0ibWVudGlvbiJdCgojIFlvdSBjYW4gYWxzbyBleGFtaW5lIHRoZSBuZXR3b3JrIG1hdHJpeCBkaXJlY3RseToKbmV0WzEsXQpuZXRbNSw3XQoKIyBHZXQgYW4gZWRnZSBsaXN0IG9yIGEgbWF0cml4Ogphc19lZGdlbGlzdChuZXQsIG5hbWVzPVQpCmFzX2FkamFjZW5jeV9tYXRyaXgobmV0LCBhdHRyPSJ3ZWlnaHQiKQoKIyBPciBkYXRhIGZyYW1lcyBkZXNjcmliaW5nIG5vZGVzIGFuZCBlZGdlczoKYXNfZGF0YV9mcmFtZShuZXQsIHdoYXQ9ImVkZ2VzIikKYXNfZGF0YV9mcmFtZShuZXQsIHdoYXQ9InZlcnRpY2VzIikKCnBsb3QobmV0KSAjIG5vdCBhIHByZXR0eSBwaWN0dXJlIQoKYGBgCiMgRGF0YXNldCAxOiAoY29udCdkKSBtYWtpbmcgbW9yZSBwcmV0dHkgcGljcwpgYGB7cn0KIyMgcmVtb3ZlIGxvb3BzIGluIGZpZ3VyZSBhYm92ZQpuZXQgPC0gc2ltcGxpZnkobmV0LCByZW1vdmUubXVsdGlwbGUgPSBGLCByZW1vdmUubG9vcHMgPSBUKSAKCiMjIHJlZHVjZSBhcnJvdyBzaXplIGFuZCByZW1vdmUgbGFiZWxzIChzZXQgdGhlbSB0byBOQSkKcGxvdChuZXQsIGVkZ2UuYXJyb3cuc2l6ZT0uNCx2ZXJ0ZXgubGFiZWw9TkEpCgojIFBsb3Qgd2l0aCBjdXJ2ZWQgZWRnZXMgKGVkZ2UuY3VydmVkPS4xKSBhbmQgcmVkdWNlIGFycm93IHNpemU6CiMgTm90ZSB0aGF0IHVzaW5nIGN1cnZlZCBlZGdlcyB3aWxsIGFsbG93IHlvdSB0byBzZWUgbXVsdGlwbGUgbGlua3MKIyBiZXR3ZWVuIHR3byBub2RlcyAoZS5nLiBsaW5rcyBnb2luZyBpbiBlaXRoZXIgZGlyZWN0aW9uLCBvciBtdWx0aXBsZXggbGlua3MpCnBsb3QobmV0LCBlZGdlLmFycm93LnNpemU9LjQsIGVkZ2UuY3VydmVkPS4xKQoKIyBTZXQgZWRnZSBjb2xvciB0byBsaWdodCBncmF5LCB0aGUgbm9kZSAmIGJvcmRlciBjb2xvciB0byBvcmFuZ2UgCiMgUmVwbGFjZSB0aGUgdmVydGV4IGxhYmVsIHdpdGggdGhlIG5vZGUgbmFtZXMgc3RvcmVkIGluICJtZWRpYSIKcGxvdChuZXQsIGVkZ2UuYXJyb3cuc2l6ZT0uMiwgZWRnZS5jb2xvcj0ib3JhbmdlIiwKICAgICB2ZXJ0ZXguY29sb3I9Im9yYW5nZSIsIHZlcnRleC5mcmFtZS5jb2xvcj0iI2ZmZmZmZiIsCiAgICAgdmVydGV4LmxhYmVsPVYobmV0KSRtZWRpYSwgdmVydGV4LmxhYmVsLmNvbG9yPSJibGFjayIpIAoKCiMjIyMgY29sb3Igb3VyIG5ldHdvcmsgbm9kZXMgYmFzZWQgb24gdHlwZSBvZiBtZWRpYQojIyMjIHNpemUgdGhlbSBiYXNlZCBvbiBkZWdyZWUgY2VudHJhbGl0eSAobW9yZSBsaW5rcyAtPiBsYXJnZXIgbm9kZSkgCiMjIyMgY2hhbmdlIHRoZSB3aWR0aCBvZiB0aGUgZWRnZXMgYmFzZWQgb24gdGhlaXIgd2VpZ2h0CiMgR2VuZXJhdGUgY29sb3JzIGJhc2VkIG9uIG1lZGlhIHR5cGU6CmNvbHJzIDwtIGMoImdyYXk1MCIsICJ0b21hdG8iLCAiZ29sZCIpClYobmV0KSRjb2xvciA8LSBjb2xyc1tWKG5ldCkkbWVkaWEudHlwZV0KCiMgQ29tcHV0ZSBub2RlIGRlZ3JlZXMgKCNsaW5rcykgYW5kIHVzZSB0aGF0IHRvIHNldCBub2RlIHNpemU6CiMgbm90ZSBhZGQgaWdyYXBoOjogYmVjYXVzZSB0aGVyZSBhcmUgMiB2ZXJzaW9ucyBvZiBkZWdyZWUKZGVnIDwtIGlncmFwaDo6ZGVncmVlKG5ldCwgbW9kZT0iYWxsIikKVihuZXQpJHNpemUgPC0gZGVnKjMKIyBXZSBjb3VsZCBhbHNvIHVzZSB0aGUgYXVkaWVuY2Ugc2l6ZSB2YWx1ZToKVihuZXQpJHNpemUgPC0gVihuZXQpJGF1ZGllbmNlLnNpemUqMC42CgojIFRoZSBsYWJlbHMgYXJlIGN1cnJlbnRseSBub2RlIElEcy4KIyBTZXR0aW5nIHRoZW0gdG8gTkEgd2lsbCByZW5kZXIgbm8gbGFiZWxzOgpWKG5ldCkkbGFiZWwgPC0gTkEKCiMgU2V0IGVkZ2Ugd2lkdGggYmFzZWQgb24gd2VpZ2h0OgpFKG5ldCkkd2lkdGggPC0gRShuZXQpJHdlaWdodC82CgojIGNoYW5nZSBhcnJvdyBzaXplIGFuZCBlZGdlIGNvbG9yOgpFKG5ldCkkYXJyb3cuc2l6ZSA8LSAuMgpFKG5ldCkkZWRnZS5jb2xvciA8LSAiZ3JheTgwIgpFKG5ldCkkd2lkdGggPC0gMStFKG5ldCkkd2VpZ2h0LzEyCnBsb3QobmV0KSAKCiMgdGhpcyBvdmVycmlkZXMgdGhlIGFib3ZlIGluIGVkZ2UuY29sb3IgYW5kIHZlcnRleC5jb2xvcgojIGF0dHJpYnV0ZXMsIHNlZSBwbG90dGluZyBwYXJhbWV0ZXJzIGJlbG93CnBsb3QobmV0LCBlZGdlLmNvbG9yPSJvcmFuZ2UiLCB2ZXJ0ZXguY29sb3I9ImdyYXk1MCIpIAoKIyBhZGQgbGVnZW5kCnBsb3QobmV0KSAKbGVnZW5kKHg9LTEuNSwgeT0tMS4xLCBjKCJOZXdzcGFwZXIiLCJUZWxldmlzaW9uIiwgIk9ubGluZSBOZXdzIiksIHBjaD0yMSwKICAgICAgIGNvbD0iIzc3Nzc3NyIsIHB0LmJnPWNvbHJzLCBwdC5jZXg9MiwgY2V4PS44LCBidHk9Im4iLCBuY29sPTEpCgojIyBkaWZmZXJlbnQgc3R5bGUgd2l0aCBvbmx5IGxhYmVscyBmb3Igbm9kZXMKcGxvdChuZXQsIHZlcnRleC5zaGFwZT0ibm9uZSIsIHZlcnRleC5sYWJlbD1WKG5ldCkkbWVkaWEsIAogICAgIHZlcnRleC5sYWJlbC5mb250PTIsIHZlcnRleC5sYWJlbC5jb2xvcj0iZ3JheTQwIiwKICAgICB2ZXJ0ZXgubGFiZWwuY2V4PS43LCBlZGdlLmNvbG9yPSJncmF5ODUiKQoKIyMgY29sb3IgdGhlIGVkZ2VzIG9mIHRoZSBncmFwaCBiYXNlZCBvbiB0aGVpciBzb3VyY2Ugbm9kZSBjb2xvci4gCiMjIGdldCB0aGUgc3RhcnRpbmcgbm9kZSBmb3IgZWFjaCBlZGdlIHdpdGggdGhlICBlbmRzKCkgaWdyYXBoIGZ1bmN0aW9uOiBJdCByZXR1cm5zIHRoZSBzdGFydCBhbmQgZW5kIHZlcnRleCBmb3IgZWRnZXMgbGlzdGVkIGluIHRoZSBlcyBwYXJhbWV0ZXIuIFRoZSBuYW1lcyBwYXJhbWV0ZXIgY29udHJvbCB3aGV0aGVyIHRoZSBmdW5jdGlvbiByZXR1cm5zIGVkZ2UgbmFtZXMgb3IgSURzLgplZGdlLnN0YXJ0IDwtIGVuZHMobmV0LCBlcz1FKG5ldCksIG5hbWVzPUYpWywxXQplZGdlLmNvbCA8LSBWKG5ldCkkY29sb3JbZWRnZS5zdGFydF0KCnBsb3QobmV0LCBlZGdlLmNvbG9yPWVkZ2UuY29sLCBlZGdlLmN1cnZlZD0uMSkgIApgYGAKIyBuZXR3b3JrIGxheW91dHMKYGBge3J9CiMjIGFsbCBhdmFpbGFibGUgbGF5b3V0cwpsYXlvdXRzIDwtIGdyZXAoIl5sYXlvdXRfIiwgbHMoInBhY2thZ2U6aWdyYXBoIiksIHZhbHVlPVRSVUUpWy0xXSAKIyBSZW1vdmUgbGF5b3V0cyB0aGF0IGRvIG5vdCBhcHBseSB0byBvdXIgZ3JhcGguCmxheW91dHMgPC0gbGF5b3V0c1shZ3JlcGwoImJpcGFydGl0ZXxtZXJnZXxub3JtfHN1Z2l5YW1hfHRyZWUiLCBsYXlvdXRzKV0KCnBhcihtZnJvdz1jKDMsMyksIG1hcj1jKDEsMSwxLDEpKQpmb3IgKGxheW91dCBpbiBsYXlvdXRzKSB7CiAgcHJpbnQobGF5b3V0KQogIGwgPC0gZG8uY2FsbChsYXlvdXQsIGxpc3QobmV0KSkgCiAgcGxvdChuZXQsIGVkZ2UuYXJyb3cubW9kZT0wLCBsYXlvdXQ9bCwgbWFpbj1sYXlvdXQpIH0KYGBgCgojIHNvbWUgbGF5b3V0IGV4YW1wbGVzCmBgYHtyfQojIyMgQmFyYWJhc2ktQWxiZXJ0IG1vZGVsIHdpdGggc2FtcGxlX3BhKG4pLCBuID0gI25vZGVzCm5ldC5iZyA8LSBzYW1wbGVfcGEoODApIApWKG5ldC5iZykkc2l6ZSA8LSA4ClYobmV0LmJnKSRmcmFtZS5jb2xvciA8LSAid2hpdGUiClYobmV0LmJnKSRjb2xvciA8LSAib3JhbmdlIgpWKG5ldC5iZykkbGFiZWwgPC0gIiIgCkUobmV0LmJnKSRhcnJvdy5tb2RlIDwtIDAKcGxvdChuZXQuYmcpCgojIyMgcmFuZG9tIGxheW91dApwbG90KG5ldC5iZywgbGF5b3V0PWxheW91dF9yYW5kb21seSkKCiMgb3IKbCA8LSBsYXlvdXRfcmFuZG9tbHkobmV0LmJnKQpwbG90KG5ldC5iZywgbGF5b3V0PWwpCgojIyMgY2lyY3VsYXIgbGF5b3V0CmwgPC0gbGF5b3V0X2luX2NpcmNsZShuZXQuYmcpCnBsb3QobmV0LmJnLCBsYXlvdXQ9bCkKCiMjIyBsYXlvdXQgd2l0aCBmaXhlZCBjb29yZGluYXRlcwpsIDwtIGNiaW5kKDE6dmNvdW50KG5ldC5iZyksIGMoMSwgdmNvdW50KG5ldC5iZyk6MikpCnBsb3QobmV0LmJnLCBsYXlvdXQ9bCkKCiMjIyAzRCBzcGhlcmUgbGF5b3V0CmwgPC0gbGF5b3V0X29uX3NwaGVyZShuZXQuYmcpCnBsb3QobmV0LmJnLCBsYXlvdXQ9bCkKYGBgCgojIEZvcmNlLWRpcmVjdGVkIGxheW91dHMKYGBge3J9CiMjIyBGcnVjaHRlcm1hbi1SZWluZ29sZCBpcyBvbmUgb2YgdGhlIG1vc3QgdXNlZCBmb3JjZS1kaXJlY3RlZCBsYXlvdXQgYWxnb3JpdGhtcyBvdXQgdGhlcmUuCiMjIyBGb3JjZS1kaXJlY3RlZCBsYXlvdXRzIHRyeSB0byBnZXQgYSBuaWNlLWxvb2tpbmcgZ3JhcGggd2hlcmUgZWRnZXMgYXJlIHNpbWlsYXIgaW4gbGVuZ3RoIGFuZCBjcm9zcyBlYWNoIG90aGVyIGFzIGxpdHRsZSBhcyBwb3NzaWJsZQojIyMgVGhleSBzaW11bGF0ZSB0aGUgZ3JhcGggYXMgYSBwaHlzaWNhbCBzeXN0ZW0uIE5vZGVzIGFyZSBlbGVjdHJpY2FsbHkgY2hhcmdlZCBwYXJ0aWNsZXMgdGhhdCByZXB1bHNlIGVhY2ggb3RoZXIgd2hlbiB0aGV5IGdldCB0b28gY2xvc2UuIFRoZSBlZGdlcyBhY3QgYXMgc3ByaW5ncyB0aGF0IGF0dHJhY3QgY29ubmVjdGVkIG5vZGVzIGNsb3NlciB0b2dldGhlci4gQXMgYSByZXN1bHQsIG5vZGVzIGFyZSBldmVubHkgZGlzdHJpYnV0ZWQgdGhyb3VnaCB0aGUgY2hhcnQgYXJlYSwgYW5kIHRoZSBsYXlvdXQgaXMgaW50dWl0aXZlIGluIHRoYXQgbm9kZXMgd2hpY2ggc2hhcmUgbW9yZSBjb25uZWN0aW9ucyBhcmUgY2xvc2VyIHRvIGVhY2ggb3RoZXIuIFRoZSBkaXNhZHZhbnRhZ2Ugb2YgdGhlc2UgYWxnb3JpdGhtcyBpcyB0aGF0IHRoZXkgYXJlIHJhdGhlciBzbG93IGFuZCB0aGVyZWZvcmUgbGVzcyBvZnRlbiB1c2VkIGluIGdyYXBocyBsYXJnZXIgdGhhbiB+MTAwMCB2ZXJ0aWNlcy4gWW91IGNhbiBzZXQgdGhlIOKAnHdlaWdodOKAnSBwYXJhbWV0ZXIgd2hpY2ggaW5jcmVhc2VzIHRoZSBhdHRyYWN0aW9uIGZvcmNlcyBhbW9uZyBub2RlcyBjb25uZWN0ZWQgYnkgaGVhdmllciBlZGdlcy4KIyMjIFlvdSB3aWxsIG5vdGljZSB0aGF0IHRoaXMgbGF5b3V0IGlzIG5vdCBkZXRlcm1pbmlzdGljIC0gZGlmZmVyZW50IHJ1bnMgd2lsbCByZXN1bHQgaW4gc2xpZ2h0bHkgZGlmZmVyZW50IGNvbmZpZ3VyYXRpb25zCmwgPC0gbGF5b3V0X3dpdGhfZnIobmV0LmJnKQpwbG90KG5ldC5iZywgbGF5b3V0PWwpCgojIyBZb3Ugd2lsbCBub3RpY2UgdGhhdCB0aGlzIGxheW91dCBpcyBub3QgZGV0ZXJtaW5pc3RpYyAtIGRpZmZlcmVudCBydW5zIHdpbGwgcmVzdWx0IGluIHNsaWdodGx5IGRpZmZlcmVudCBjb25maWd1cmF0aW9ucy4gCnBhcihtZnJvdz1jKDIsMiksIG1hcj1jKDAsMCwwLDApKSAgICMgcGxvdCBmb3VyIGZpZ3VyZXMgLSAyIHJvd3MsIDIgY29sdW1ucwpwbG90KG5ldC5iZywgbGF5b3V0PWxheW91dF93aXRoX2ZyKQpwbG90KG5ldC5iZywgbGF5b3V0PWxheW91dF93aXRoX2ZyKQpwbG90KG5ldC5iZywgbGF5b3V0PWwpCnBsb3QobmV0LmJnLCBsYXlvdXQ9bCkKZGV2Lm9mZigpCgoKIyMjIEthbWFkYSBLYXdhaSBmb3JjZSBkaXJlY3RlZAojIyMgTGlrZSBGcnVjaHRlcm1hbiBSZWluZ29sZCwgaXQgYXR0ZW1wdHMgdG8gbWluaW1pemUgdGhlIGVuZXJneSBpbiBhIHNwcmluZyBzeXN0ZW0uCmwgPC0gbGF5b3V0X3dpdGhfa2sobmV0LmJnKQpwbG90KG5ldC5iZywgbGF5b3V0PWwpCgojIyMgVGhlIExHTCBhbGdvcml0aG0gaXMgbWVhbnQgZm9yIGxhcmdlLCBjb25uZWN0ZWQgZ3JhcGhzLiAKIyMjIEhlcmUgeW91IGNhbiBhbHNvIHNwZWNpZnkgYSByb290OiBhIG5vZGUgdGhhdCB3aWxsIGJlIHBsYWNlZCBpbiB0aGUgbWlkZGxlIG9mIHRoZSBsYXlvdXQuCnBsb3QobmV0LmJnLCBsYXlvdXQ9bGF5b3V0X3dpdGhfbGdsKQpgYGAKCiMgTURTIChtdWx0aWRpbWVuc2lvbmFsIHNjYWxpbmcpIGFsZ29yaXRobQpgYGB7cn0KIyMgdHJpZXMgdG8gcGxhY2Ugbm9kZXMgYmFzZWQgb24gc29tZSBtZWFzdXJlIG9mIHNpbWlsYXJpdHkgb3IgZGlzdGFuY2UgYmV0d2VlbiB0aGVtLiBNb3JlIHNpbWlsYXIgbm9kZXMgYXJlIHBsb3R0ZWQgY2xvc2VyIHRvIGVhY2ggb3RoZXIuIEJ5IGRlZmF1bHQsIHRoZSBtZWFzdXJlIHVzZWQgaXMgYmFzZWQgb24gdGhlIHNob3J0ZXN0IHBhdGhzIGJldHdlZW4gbm9kZXMgaW4gdGhlIG5ldHdvcmsuIFdlIGNhbiBjaGFuZ2UgdGhhdCBieSB1c2luZyBvdXIgb3duIGRpc3RhbmNlIG1hdHJpeCAoaG93ZXZlciBkZWZpbmVkKSB3aXRoIHRoZSBwYXJhbWV0ZXIgIGRpc3QuIE1EUyBsYXlvdXRzIGFyZSBuaWNlIGJlY2F1c2UgcG9zaXRpb25zIGFuZCBkaXN0YW5jZXMgaGF2ZSBhIGNsZWFyIGludGVycHJldGF0aW9uLiBUaGUgcHJvYmxlbSB3aXRoIHRoZW0gaXMgdmlzdWFsIGNsYXJpdHk6IG5vZGVzIG9mdGVuIG92ZXJsYXAsIG9yIGFyZSBwbGFjZWQgb24gdG9wIG9mIGVhY2ggb3RoZXIuCnBsb3QobmV0LmJnLCBsYXlvdXQ9bGF5b3V0X3dpdGhfbWRzKQpgYGAKCiMgRGF0YXNldCAyOiBpbnB1dCA9IG1hdHJpeCBmb3JtYXQKYGBge3J9CiMjIyMgZGF0YXNldCAyCm5vZGVzMiA8LSByZWFkLmNzdigiL1VzZXJzL2ppZW1pbmdjaGVuL1JfY29kZXMvcG9sbmV0MjAxN19uZXR3b3Jrc190dXRvcmlhbC9EYXRhIGZpbGVzL0RhdGFzZXQyLU1lZGlhLVVzZXItRXhhbXBsZS1OT0RFUy5jc3YiLCBoZWFkZXI9VCwgYXMuaXM9VCkKbGlua3MyIDwtIHJlYWQuY3N2KCIvVXNlcnMvamllbWluZ2NoZW4vUl9jb2Rlcy9wb2xuZXQyMDE3X25ldHdvcmtzX3R1dG9yaWFsL0RhdGEgZmlsZXMvRGF0YXNldDItTWVkaWEtVXNlci1FeGFtcGxlLUVER0VTLmNzdiIsIGhlYWRlcj1ULCByb3cubmFtZXM9MSkKCmhlYWQobm9kZXMyKQpoZWFkKGxpbmtzMikKCmxpbmtzMiA8LSBhcy5tYXRyaXgobGlua3MyKQpkaW0obGlua3MyKQpkaW0obm9kZXMyKQoKIyMgcmVhZCBuZXR3b3JrIHVzaW5nIGdyYXBoX2Zyb21faW5jaWRlbmNlCiMjIEluIGlncmFwaCwgYmlwYXJ0aXRlIG5ldHdvcmtzIGhhdmUgYSBub2RlIGF0dHJpYnV0ZSBjYWxsZWQgdHlwZSB0aGF0IGlzIEZBTFNFIChvciAwKSBmb3IgdmVydGljZXMgaW4gb25lIG1vZGUgYW5kIFRSVUUgKG9yIDEpIGZvciB0aG9zZSBpbiB0aGUgb3RoZXIgbW9kZS4KIyMgVG8gdHJhbnNmb3JtIGEgb25lLW1vZGUgbmV0d29yayBtYXRyaXggaW50byBhbiBpZ3JhcGggb2JqZWN0LCB1c2UgZ3JhcGhfZnJvbV9hZGphY2VuY3lfbWF0cml4KCkuCm5ldDIgPC0gZ3JhcGhfZnJvbV9pbmNpZGVuY2VfbWF0cml4KGxpbmtzMikKdGFibGUoVihuZXQyKSR0eXBlKQpgYGAKIyBpbnRlcmFjdGl2ZSBuZXR3b3JrcwpgYGB7cn0KIyBpbnN0YWxsLnBhY2thZ2VzKCdhbmltYXRpb24nKQojIGluc3RhbGwucGFja2FnZXMoJ3Zpc05ldHdvcmsnKQpsaWJyYXJ5KCd2aXNOZXR3b3JrJykgCmxpYnJhcnkoJ2FuaW1hdGlvbicpIApsaWJyYXJ5KCdpZ3JhcGgnKQoKdmlzTmV0d29yayhub2RlcywgbGlua3MsIHdpZHRoPSIxMDAlIiwgaGVpZ2h0PSI0MDBweCIsIG1haW49Ik5ldHdvcmshIikKYGBgCgojIHBsb3R0aW5nIHBhcmFtZXRlcnMKYGBge3J9CgojIyA/aWdyYXBoLnBsb3R0aW5nIGZvciBtb3JlIGluZm9ybWF0aW9uLgojIyBOT0RFUwkgCiMgdmVydGV4LmNvbG9yCSBOb2RlIGNvbG9yCiMgdmVydGV4LmZyYW1lLmNvbG9yCSBOb2RlIGJvcmRlciBjb2xvcgojIHZlcnRleC5zaGFwZQkgT25lIG9mIOKAnG5vbmXigJ0sIOKAnGNpcmNsZeKAnSwg4oCcc3F1YXJl4oCdLCDigJxjc3F1YXJl4oCdLCDigJxyZWN0YW5nbGXigJ0KIyAg4oCcY3JlY3RhbmdsZeKAnSwg4oCcdnJlY3RhbmdsZeKAnSwg4oCccGll4oCdLCDigJxyYXN0ZXLigJ0sIG9yIOKAnHNwaGVyZeKAnQojIHZlcnRleC5zaXplCSBTaXplIG9mIHRoZSBub2RlIChkZWZhdWx0IGlzIDE1KQojIHZlcnRleC5zaXplMgkgVGhlIHNlY29uZCBzaXplIG9mIHRoZSBub2RlIChlLmcuIGZvciBhIHJlY3RhbmdsZSkKIyB2ZXJ0ZXgubGFiZWwJIENoYXJhY3RlciB2ZWN0b3IgdXNlZCB0byBsYWJlbCB0aGUgbm9kZXMKIyB2ZXJ0ZXgubGFiZWwuZmFtaWx5CSBGb250IGZhbWlseSBvZiB0aGUgbGFiZWwgKGUuZy7igJxUaW1lc+KAnSwg4oCcSGVsdmV0aWNh4oCdKQojIHZlcnRleC5sYWJlbC5mb250CSBGb250OiAxIHBsYWluLCAyIGJvbGQsIDMsIGl0YWxpYywgNCBib2xkIGl0YWxpYywgNSBzeW1ib2wKIyB2ZXJ0ZXgubGFiZWwuY2V4CSBGb250IHNpemUgKG11bHRpcGxpY2F0aW9uIGZhY3RvciwgZGV2aWNlLWRlcGVuZGVudCkKIyB2ZXJ0ZXgubGFiZWwuZGlzdAkgRGlzdGFuY2UgYmV0d2VlbiB0aGUgbGFiZWwgYW5kIHRoZSB2ZXJ0ZXgKIyB2ZXJ0ZXgubGFiZWwuZGVncmVlCSBUaGUgcG9zaXRpb24gb2YgdGhlIGxhYmVsIGluIHJlbGF0aW9uIHRvIHRoZSB2ZXJ0ZXgsIHdoZXJlCiMgIDAgaXMgcmlnaHQsIOKAnHBp4oCdIGlzIGxlZnQsIOKAnHBpLzLigJ0gaXMgYmVsb3csIGFuZCDigJwtcGkvMuKAnSBpcyBhYm92ZQojIEVER0VTCiMgZWRnZS5jb2xvcgkgRWRnZSBjb2xvcgojIGVkZ2Uud2lkdGgJIEVkZ2Ugd2lkdGgsIGRlZmF1bHRzIHRvIDEKIyBlZGdlLmFycm93LnNpemUJIEFycm93IHNpemUsIGRlZmF1bHRzIHRvIDEKIyBlZGdlLmFycm93LndpZHRoCSBBcnJvdyB3aWR0aCwgZGVmYXVsdHMgdG8gMQojIGVkZ2UubHR5CSBMaW5lIHR5cGUsIGNvdWxkIGJlIDAgb3Ig4oCcYmxhbmvigJ0sIDEgb3Ig4oCcc29saWTigJ0sIDIgb3Ig4oCcZGFzaGVk4oCdLAojICAzIG9yIOKAnGRvdHRlZOKAnSwgNCBvciDigJxkb3RkYXNo4oCdLCA1IG9yIOKAnGxvbmdkYXNo4oCdLCA2IG9yIOKAnHR3b2Rhc2jigJ0KIyBlZGdlLmxhYmVsCSBDaGFyYWN0ZXIgdmVjdG9yIHVzZWQgdG8gbGFiZWwgZWRnZXMKIyBlZGdlLmxhYmVsLmZhbWlseQkgRm9udCBmYW1pbHkgb2YgdGhlIGxhYmVsIChlLmcu4oCcVGltZXPigJ0sIOKAnEhlbHZldGljYeKAnSkKIyBlZGdlLmxhYmVsLmZvbnQJIEZvbnQ6IDEgcGxhaW4sIDIgYm9sZCwgMywgaXRhbGljLCA0IGJvbGQgaXRhbGljLCA1IHN5bWJvbAojIGVkZ2UubGFiZWwuY2V4CSBGb250IHNpemUgZm9yIGVkZ2UgbGFiZWxzCiMgZWRnZS5jdXJ2ZWQJIEVkZ2UgY3VydmF0dXJlLCByYW5nZSAwLTEgKEZBTFNFIHNldHMgaXQgdG8gMCwgVFJVRSB0byAwLjUpCiMgYXJyb3cubW9kZQkgVmVjdG9yIHNwZWNpZnlpbmcgd2hldGhlciBlZGdlcyBzaG91bGQgaGF2ZSBhcnJvd3MsCiMgIHBvc3NpYmxlIHZhbHVlczogMCBubyBhcnJvdywgMSBiYWNrLCAyIGZvcndhcmQsIDMgYm90aAojIE9USEVSCiMgbWFyZ2luCSBFbXB0eSBzcGFjZSBtYXJnaW5zIGFyb3VuZCB0aGUgcGxvdCwgdmVjdG9yIHdpdGggbGVuZ3RoIDQKIyBmcmFtZQkgaWYgVFJVRSwgdGhlIHBsb3Qgd2lsbCBiZSBmcmFtZWQKIyBtYWluCSBJZiBzZXQsIGFkZHMgYSB0aXRsZSB0byB0aGUgcGxvdAojIHN1YgkgSWYgc2V0LCBhZGRzIGEgc3VidGl0bGUgdG8gdGhlIHBsb3QKIyBhc3AJICBOdW1lcmljLCB0aGUgYXNwZWN0IHJhdGlvIG9mIGEgcGxvdCAoeS94KS4KIyBwYWxldHRlCSBBIGNvbG9yIHBhbGV0dGUgdG8gdXNlIGZvciB2ZXJ0ZXggY29sb3IKIyByZXNjYWxlCSBXaGV0aGVyIHRvIHJlc2NhbGUgY29vcmRpbmF0ZXMgdG8gWy0xLDFdLiBEZWZhdWx0IGlzIFRSVUUuCgpgYGA=